import React, { Component, PropTypes } from 'react'
import {checkButtonDisabled, messages} from "share/common";
import errorMessage from 'share/errorMessage'
import moment from 'moment'
import { Tag, Radio, Select, Menu, Dropdown, Icon, Switch, message } from "antd";
import Condition from 'components/condition'
import SlideExpenseReportDetailExpenseListTable from './slide-expense-report-expense-list-table'
import ExpenseAccountTable from 'containers/expense-report/components/expense-account-table'
import expenseReportFunction from 'containers/expense-report/expense-report.function'
import autoAuditService from 'containers/finance-setting/auto-audit/auto-audit.service'
import AuditExpenseDetail from "../../../invoice-bag-approve/invoice-bag-approve-detail/audit-expense-detail";
import CommonModal from 'containers/expense/component/common-modal'
import ExpenseDetail from 'containers/expense'

const { If, Else } = Condition;
const { CheckableTag } = Tag;
const { invoiceColumnsCompare } = expenseReportFunction;

class SlideExpenseReportDetailExpenseList extends Component {

  onSelectExpense = keys => {
    const { onSelectExpense = () => {} } = this.props;
    onSelectExpense(keys);
  };

  state = {
    manualAuditLoading: false,
    invoiceLabels: [],
    nowExpense: null,
    showExpenseDetail: false,
    nowExpenseDataSource: [],
    filter: {
      auditTab: 'all', //全部、待审核、已审核
      includeLabel: true,
      label: []
    },
    hasAttachmentChange: false,
    auditEditable: false, //财务审核时，费用是否为编辑状态
    sorter: {},
    needRefresh: false,
    refreshExpenseList: false, //只刷新费用列表
  };

  tableRefMap = [];

  componentDidMount() {
    this.setAuditTab();
    const { onClickCollapse } = this.props;
    this.getInvoiceLabel();
    onClickCollapse(this.tableRefMap);
  }

  setAuditTab = () => {
    let { filter } = this.state;
    const tabStorage = localStorage.getItem("finance-view-invoice-auditTab");
    if (this.context.readOnly) {
      filter.auditTab = 'all';
    } else if (['true', 'false'].includes(tabStorage)) {
      filter.auditTab = JSON.parse(tabStorage);
    } else {
      filter.auditTab = tabStorage || false;
    }
    this.setState({ filter })
  };

  filterExpenseByCalendarMode = record => {
    const { filterCondition } = this.props;
    const { ownerOID, expenseTypeOID, date } = filterCondition;
    return (!ownerOID.length || ownerOID.indexOf(record.invoiceView.ownerOID) > -1) &&
      (!expenseTypeOID.length || expenseTypeOID.indexOf(record.invoiceView.expenseTypeOID) > -1) &&
      (!date.length || date.indexOf(moment(record.invoiceView.createdDate).format("YYYY-MM-DD ddd")) > -1);
  };

  filterExpense = record => {
    const { filter } = this.state;
    let recordIncludeLabel = record.invoiceView.invoiceLabels.find(label => filter.label.indexOf(label.type) > -1);
    let labels = filter.label.length === 0 || (filter.includeLabel ? recordIncludeLabel : !recordIncludeLabel);
    return filter.auditTab === 'all' ? labels : (!!record.invoiceView.manualAudit === filter.auditTab && labels)
  };

  getInvoiceLabel = () => {
    const { invoiceData: { expenseReportInvoices } } = this.props;
    const { filter } = this.state;
    let invoiceLabels = [];
    expenseReportInvoices
      .filter(item => filter.auditTab === 'all' ? true : !!item.invoiceView.manualAudit === filter.auditTab)
      .map(invoice => {
      invoice.invoiceView.invoiceLabels.map(label => {
        if(!invoiceLabels.find(l => l.type === label.type))
          invoiceLabels.push({
            name: label.name,
            type: label.type,
            level: label.level
          })
      })
    });
    this.setState({ invoiceLabels });
  };

  editNowExpenseCallBack = expense => {
    const { getExpenseList } = this.props;
    return new Promise(resolve => {
      if (expense && expense.invoiceOID) {
        getExpenseList().then(() => {
          resolve(expense);
        }).catch(() => {
          resolve(expense)
        })
      }
    })
  };

  switchingExpense = index => {
    let { nowExpenseDataSource } = this.state;
    let nowExpense = nowExpenseDataSource[index];
    this.setState({ nowExpense })
  };

  handleAnnotateOnChange = () => {
    this.setState({ needRefresh: true });
  };

  handleCloseExpenseDetail = (refresh, rejectAll) => {
    const { needRefresh, refreshExpenseList } = this.state;
    const { getExpenseList, getReportInfo } = this.props;
    const { info: { expenseReportOID } } = this.context;
    if (rejectAll) {
      this.props.goBack(true);
    } else {
      (refresh || needRefresh || refreshExpenseList) && getExpenseList();
      (refresh || needRefresh) && getReportInfo({ expenseReportOID }, false);
      this.setState({ showExpenseDetail: false, nowExpense: null, auditEditable: false, refreshExpenseList: false });
    }
  };

  onChangeFilter = (key, value) => {
    let { filter } = this.state;
    filter[key] = value;
    if (key === 'auditTab') {
      filter.label = [];
      localStorage.setItem("finance-view-invoice-auditTab", value);
    }
    this.setState({ filter }, this.getInvoiceLabel );
  };

  onChangeTag = (checked, type) => {
    const { filter } = this.state;
    if(checked)
      filter.label.push(type);
    else
      filter.label.delete(type);
    this.setState({ filter });
  };

  static contextTypes = {
    info: PropTypes.object,
    jobInfo: PropTypes.object,
    auditCapability: PropTypes.bool,
    isWaitForAudit: PropTypes.bool,
    isAuditEditable: PropTypes.bool,
    mode: PropTypes.string,
    readOnly: PropTypes.bool,
    entry: PropTypes.string
  };

  onCloseCalendarModeTag = type => {
    const { filterCondition, filterData } = this.props;
    filterCondition[type === 'date' ? type : type + "OID"] = [];
    filterData(filterCondition);
  };

  getNormalData = expenseReportInvoices => {
    const { sorter } = this.state;
    // 行程模式查看处理
    if (this.props.mode === 'itinerary') {
      return this.props.currentViewExpenseList;
    }
    return expenseReportInvoices
      .filter(this.filterExpense)
      .filter(this.filterExpenseByCalendarMode)
      .map(invoice => invoice.invoiceView)
      .sort(invoiceColumnsCompare(sorter.columnKey, sorter.order))
  };

  handleSwitchNew = () => {
    window.localStorage.setItem('hly.auto.check', 'false');
    const { isAuditEditable, isWaitForAudit, jobInfo, info: expenseReport } = this.context;
    const { invoiceData: { expenseReportInvoices } } = this.props;
    const { nowExpense, filter: { auditTab } } = this.state;
    this.setState({ showExpenseDetail: false }, () => {
      CommonModal.open(
        {
          jobInfo,
          auditTab: auditTab.toString(),
          nowExpense,
          expenseReport,
          isWaitForAudit,
          isAuditEditable,
          expenseReportInvoices: expenseReportInvoices.map(item => item.invoiceView),
          handleClose: this.handleClose,
          children: <ExpenseDetail/>
        }, this);
    });
  };


  handleClose = (params = {}) => {
    const { isEdit, isSwitchOld, refresh, rejectAll } = params;
    if (isSwitchOld || isEdit) {
      isSwitchOld && window.localStorage.setItem('hly.auto.check', 'true');
      this.setState({ showExpenseDetail: true });
      return;
    }
    this.handleCloseExpenseDetail(refresh, rejectAll);
  };

  openExpense = (record, dataSource) => {
    const { invoiceData: { expenseReportInvoices } } = this.props;
    let isNew = window.localStorage.getItem('hly.auto.check') === 'false' && this.context.entry !== 'view';
    this.setState({
      showExpenseDetail: !isNew,
      nowExpense: record,
      nowExpenseDataSource: dataSource || this.getNormalData(expenseReportInvoices)
    }, () => isNew && this.handleSwitchNew());
  };

  renderFilterMenu = (
    <Menu onClick={e => this.onChangeFilter('includeLabel', JSON.parse(e.key))}>
      <Menu.Item key={true}>{messages('expense-14.key278')/*标签包含*/}</Menu.Item>
      <Menu.Item key={false}>{messages('expense-14.key279')/*标签不包含*/}</Menu.Item>
    </Menu>
  );

  //人工审核标记
  handleManualAudit = checked => {
    const { info: { expenseReportOID } } = this.context;
    let { nowExpense } = this.state;
    let params = {
      invoiceOIDs: [nowExpense.invoiceOID],
      expenseReportOID,
      manualAudit: checked
    };
    this.setState({ manualAuditLoading: true });
    autoAuditService.setManualAudit(params).then(() => {
      nowExpense.manualAudit = checked;
      this.setState({ manualAuditLoading: false, refreshExpenseList: true, nowExpense });
      message.success(messages('common.operate.success')/*操作成功*/);
    }).catch(e => {
      this.setState({ manualAuditLoading: false });
      errorMessage(e.response);
    })
  };

  //需求12405
  getChangeInvoiceEnable = () => {
    const { entry, info } = this.context;
    let status = '' + info.status;
    return entry === 'view' && !checkButtonDisabled('change-invoice') && (
      status === '1004' ||
      status === '1007' ||
      status === '1008' ||
      status === '1005'
    )
  };

  render() {
    const {
      invoiceData: { invoiceGroups, expenseReportInvoices }, costCenterItemsApportion,
      filterCondition, filterData, tableLoading, mode, selectedExpense, activeTab
    } = this.props;
    const { jobInfo, auditCapability, info, isWaitForAudit, isAuditEditable, readOnly, entry } = this.context;
    const {
      invoiceLabels, nowExpense, showExpenseDetail, filter, nowExpenseDataSource,
      auditEditable, sorter
    } = this.state;
    let conditions = filterCondition.ownerOID.length + filterCondition.expenseTypeOID.length + filterCondition.date.length;
    let label = {
      'owner': messages('expense-14.key195')/*归属人*/,
      'expenseType': messages('common.expense.type')/*费用类型*/,
      'date': messages('common.happened.date')/*发生日期*/
    };
    let rowSelection = {
      selectedRowKeys: selectedExpense || [],
      type: 'checkbox',
      onChange: this.onSelectExpense
    };
    let getInvoiceNum = flag => expenseReportInvoices.filter(item => !!item.invoiceView.manualAudit === flag).length;
    return (
      <div className='slide-expense-report-detail-expense-list'>
        <If value={!readOnly && mode !== 'itinerary'}>
          <Radio.Group value={filter.auditTab} onChange={e => this.onChangeFilter('auditTab', e.target.value)}>
            <Radio.Button value="all">{messages('common.all')/*全部*/}</Radio.Button>
            <Radio.Button value={false}>{messages('expense-14.key281')/*待审核*/} ({getInvoiceNum(false)})</Radio.Button>
            <Radio.Button value={true}>{messages('expense-14.key280')/*已审核*/} ({getInvoiceNum(true)})</Radio.Button>
          </Radio.Group>
        </If>
        {invoiceLabels.length > 0 && mode !== 'itinerary' && (
          <div className='invoice-label-filter'>
            <Dropdown overlay={this.renderFilterMenu}>
              <span>
                {filter.includeLabel ?
                  messages('expense-14.key278')/*标签包含*/ :
                  messages('expense-14.key279')/*标签不包含*/}
                <Icon type="down" style={{ margin: '0 10px 0 5px' }}/>
              </span>
            </Dropdown>
            {invoiceLabels.map(label => <CheckableTag
              checked={filter.label.indexOf(label.type) > -1}
              onChange={checked => this.onChangeTag(checked, label.type)}
            >
              {label.name}
            </CheckableTag>)}
          </div>
        )}
        <If value={conditions}>
          {messages('expense-14.key283')/*日历模式筛选*/}：
          {Object.keys(filterCondition).filter(key => Object.keys(label).indexOf(key) > -1).map(key => {
            return (!!filterCondition[key].length &&
              <Tag closable onClose={() => this.onCloseCalendarModeTag(key)}>{label[key]}：{filterCondition[key].join(key === 'date' ? "~" : "、")}</Tag>
            )
          })}
          <a className='default-color-font' onClick={() => filterData(null)}>
            &nbsp;&nbsp;
            {messages('expense-14.key284')/*清空日历模式筛选*/}
          </a>
        </If>
        <Condition>
          <If value={mode === 'classify'}>
            {invoiceGroups.sort((a, b) => a.sequence - b.sequence).map((group, index) => (
              <SlideExpenseReportDetailExpenseListTable
                showEmpty={index === 0 && this.getNormalData(expenseReportInvoices).length === 0}
                group={group}
                filterExpense={this.filterExpense}
                filterExpenseByCalendarMode={this.filterExpenseByCalendarMode}
                expenseReportInvoices={expenseReportInvoices}
                rowSelection={rowSelection}
                onOpenExpenseDetail={this.openExpense}
                onClickCollapse={params => this.tableRefMap.push(params)}
                tableLoading={tableLoading}
                sorter={sorter}
                onChange={(pagination, filters, sorter) => this.setState({ sorter: sorter || {} })}
              />
            ))}
          </If>
          <Else>
            <ExpenseAccountTable
              loading={tableLoading}
              readOnly
              isWaitForAudit={isWaitForAudit}
              isAuditEditable={isAuditEditable}
              showExpenseReportInvoices={this.getNormalData(expenseReportInvoices)}
              filterCondition={filterCondition}
              expenseRowSelection={rowSelection}
              itineraryMod={mode === 'itinerary'}
              info={info}
              pageFrom='newAuditView'
              handleView={this.openExpense}
              handleRowClick={this.openExpense}
              onChange={(pagination, filters, sorter) => this.setState({ sorter: sorter || {} })}
              changeInvoiceEnable={this.getChangeInvoiceEnable()}
            />
          </Else>
        </Condition>
        {showExpenseDetail && (
          <AuditExpenseDetail
            visible={showExpenseDetail}
            invoiceOID={nowExpense.invoiceOID}
            expenseReportOID={info.expenseReportOID}
            isWaitForAudit={isWaitForAudit}
            isAuditEditable={isAuditEditable}
            record={nowExpense}
            info={info}
            jobInfo={jobInfo}
            invoiceList={expenseReportInvoices}
            showExpenseReportInvoices={nowExpenseDataSource}
            switchingInvoice={this.switchingExpense}
            annotateOnChange={this.handleAnnotateOnChange}
            close={this.handleCloseExpenseDetail}
            handleSwitchNew={this.handleSwitchNew}
            isShowNewBotton={activeTab === 'expense'}
            changeInvoiceEnable={this.getChangeInvoiceEnable()}
          />
        )}
      </div>
    )
  }

}

export default SlideExpenseReportDetailExpenseList;
